package ${packageName}.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Date;
import java.util.TreeMap;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;

import org.apache.commons.lang.StringUtils;
import cn.com.gc.frame.enums.SysDefineEnumType;


import com.google.common.collect.Lists;
import cn.com.gc.core.db.DynamicDataSource;
import SignParam;
import Page;
import ${packageName}.cache.${name}Cache;
import ${packageName}.model.${name};

/**
 * @ClassName: ${name}Dao.java
 * @Description: ${description}的数据交互处理类
 * @author ${author}
 * @date   ${newdate}
 * @version V1.0.0
 * <p>
 * ----------------------------------------------------------------------------
 *  modifyer    modifyTime                 comment
 *
 * ----------------------------------------------------------------------------
 * </p>
 */
@Component
public class ${name}Dao extends ${name}Cache{

	@Autowired
	private ${dataSource} ${dataSourceLower};

	private final String SQL = "SELECT  ${columnStr} ";

	/**
	 * 保存创建${name},并且保存到缓存中
	 * @param ${nameLower}
	 */
      public ${name} save${name}(${name} ${nameLower}){
        if(null == ${nameLower})
            return  null;
		String sql = "INSERT INTO ${table} (${columnStr}) "
		           + "VALUES(${columnVal}) ";
		${insert}
	    long id = ${dataSourceLower}.insert(sql, "${id}", ${dbList});
	    if(id > 0){
	      ${nameLower}.setId(id);
	      this.addCache(${nameLower});//增加到缓存
	      return ${nameLower};
	    }
	    return null;

      }


	/**
	 * 更新${nameLower}信息,where条件为${nameLower}Id,更新${nameLower}
	 * @param ${nameLower}
	 */
	public boolean update${name}(${name} ${nameLower}){
		boolean flg = false ;
		if(null == ${nameLower})
		   return  flg;
		String sql = "UPDATE ${table} SET ${columnSet} "
		           + " WHERE ${id} = ? " ;

		${update}
		${updatewhere}
	    flg = ${dataSourceLower}.update(sql,${dbList});
	    if(flg){
	    	this.addCache( ${nameLower}); //更新到缓存;
	    }return flg;

	}

	/**
	 * 通过主键${nameLower}Id删除${nameLower}
	 *  @param ${nameLower}Id
	 */
	public boolean  del${name}ById(long ${nameLower}Id){
		if(${nameLower}Id == 0)
	        return false;
		String sql = " DELETE FROM ${table} WHERE ${id} = ? ";
		this.delCache(${name}.class,${nameLower}Id);//删除缓存
		return ${dataSourceLower}.update(sql,${nameLower}Id);

	}


	/**
	 * 通过主键${nameLower}删除${nameLower}
	 *  @param ${nameLower}
	 */
	public boolean  del${name}(${name} ${nameLower}){
		if(null == ${nameLower} || ${nameLower}.getId() < 0)
	        return false;
		String sql = " DELETE FROM ${table} WHERE ${id} = ? ";
		this.delCache(${nameLower});//删除缓存
		return ${dataSourceLower}.update(sql,${nameLower}.getId());

	}

		/**
	 * 通过主键${nameLower}Id查找${name}
	 * @param ${nameLower}
	 */
	public ${name} get${name}(${name} ${nameLower}){
		if(null == ${nameLower} || ${nameLower}.getId() < 0){
		   return  null;
		}
		long id =  ${nameLower}.getId();
		${nameLower} = this.findCache(${nameLower} );//从缓存中查找
		if(null != ${nameLower}){
			return ${nameLower};
		}
		String sql = SQL
		              + " FROM ${table}  WHERE ${id} = ? ";

		${nameLower} = ${dataSourceLower}.queryT(sql, ${nameLower}Mapper, id);
		if(null == ${nameLower}){
			return null;
		}
		this.addCache(${nameLower});//增加到缓存;
		return  ${nameLower};
	}

	/**
	 * 通过主键${nameLower}Id查找${name}
	 * @param ${nameLower}Id
	 */
	public ${name} get${name}ById(long ${nameLower}Id){
		if(${nameLower}Id <= 0)
		   return  null;
		${name} ${nameLower} = this.findCacheById(${name}.class, ${nameLower}Id );//从缓存中查找
		if(null != ${nameLower}){
			return ${nameLower};
		}
		String sql = SQL
		       + " FROM ${table}  WHERE ${id} = ? ";

		${nameLower} = ${dataSourceLower}.queryT(sql, ${nameLower}Mapper, ${nameLower}Id);
		if(null == ${nameLower}){
			return null;
		}
		this.addCache(${nameLower});//增加到缓存;
		return  ${nameLower};
	}


	/**
	 * 通过主键id集合批量查找${name} Collection<Long>
	 * @param colle
	 */
	public List<${name}>  get${name}ListByIdList(Collection<Long> colle){
		if(null == colle || colle.isEmpty()) {
		   return  null;
		}
		List<${name}> list = new ArrayList<>();
		//查找从缓存中没有查找到的${name}实现;
		Map<Long,${name}> map = this.findMapCache(${name}.class, colle );//从缓存中查找
		if(null != map ){
			 list = new ArrayList<>( map.values());
			 if( map.size() == colle.size()){
				 return list;
			 }
		}
		//查找从缓存中没有查找到的OpusInfo实现;
		if(null != map && !map.isEmpty()){
			Set<Long> mapkeys = map.keySet();
			colle.removeAll(mapkeys);//删除已查到的对象信息;
		}
		//删除之后为空集合,返回上面结果;
		if(colle.isEmpty()){
			return list;
		}

		String sql = SQL
		          + " FROM ${table}  WHERE ${id} IN ( ? ) ";

		if(colle.size() > ${dataSourceLower}.LISTS_PARTITON_SIZE){
			/*** 如果大于100条,则查用分页查询;返回结果值; */
			List<List<Long>> partition = Lists.partition(new ArrayList<>(colle),  ${dataSourceLower}.LISTS_PARTITON_SIZE);
			if(CollectionUtils.isNotEmpty(partition)){
				for(List<Long> colles : partition ){
					List<${name}>  dblist = ${dataSourceLower}.queryByInToList(sql, ${nameLower}Mapper, colles);
					if(null != dblist && !dblist.isEmpty()){
						this.addCacheList(new ${name}(), dblist);
						list.addAll(dblist);
					}
				}
			}
		}else{

			List<${name}>  dblist = ${dataSourceLower}.queryByInToList(sql, ${nameLower}Mapper, colle);
			if(null != dblist && !dblist.isEmpty()){
				this.addCacheList(new ${name}(), dblist);
				list.addAll(dblist);
			}
		}
		return  list;
	}

	/**
	 * 通过主键id集合批量查找${name}
	 * @param colle
	 */
	public Map<Long,${name}>  get${name}MapByIdList(Collection<Long> colle){
		int pageSize = 100;
		if(CollectionUtils.isEmpty(colle)){
			return new HashMap<Long, ${name}>();
		}
		Map<Long,${name}> map = this.findMapCache(${name}.class, colle);
		if(null != map && map.size() == colle.size() ){
			return map;
		}
		//查找从缓存中没有查找到的OpusInfo实现;
		if(null != map && !map.isEmpty()){
			Set<Long> mapkeys = map.keySet();
			colle.removeAll(mapkeys);//删除已查到的对象信息;
		}
		if(map == null){
			map = new HashMap<>();
		}
		List<${name}> list = new ArrayList<>();
		String sql = SQL
				+ " FROM ${table}  WHERE ${id} in ( ? )  ";
		/** 如果批量id 少于指定值时100条,直接查询**/
		if(colle.size() < pageSize && !colle.isEmpty()){
			list = ${dataSourceLower}.queryByInToList(sql, ${nameLower}Mapper, colle);
		}else{
			/*** 如果大于100条,则查用分页查询;返回结果值; */
			List<List<Long>> partition = Lists.partition(new ArrayList<>(colle), pageSize);
			if(CollectionUtils.isNotEmpty(partition)){
				for(List<Long> ids : partition ){
					List<${name}> dblist = ${dataSourceLower}.queryByInToList(sql,${nameLower}Mapper, ids);
					if(null != dblist && !dblist.isEmpty()){
						list.addAll(dblist);
					}
				}
			}

		}
		//从db中批量查找作品信息;
		if(CollectionUtils.isNotEmpty(list)){
			for (${name} ${nameLower} : list) {
				map.put(${nameLower}.getId(), ${nameLower});
			}
			this.addCacheList(new ${name}(), list);

		}
		return map;
	}
	/**
	 * 通过分页Pager查找${name}
	 * @param page
	 */
	//@Deprecated
	public List<${name}>  get${name}ListByPage(Page page){
		if(null == page ) {
		   return  null;
		}
		//需要自己实现相关的分页和缓存业务
		String sql = SQL
		        + " FROM ${table}  WHERE 1 =1 limit ? offset ?  ";

		String redisKey = this.getListForRedisKey("",${name}.class,
			page.getPageSize(), page.getStart());

		List<${name}> list  = this.findResultByCache(redisKey,${name}.class);//从缓存中查找
		if(null != list && !list.isEmpty()){
			return list;
		}
		list = ${dataSourceLower}.query(sql, ${nameLower}Mapper ,page.getPageSize() ,page.getStart());
		if(null != list && !list.isEmpty()){
			this.addResultToCache(redisKey,list);
		}
		return  list;

	}



	/**
	 * 查询使用映射对象Mapper
	 * @param ${nameLower}Mapper
	 */
	private RowMapper<${name}> ${nameLower}Mapper = new RowMapper<${name}>() {
		@Override
		public ${name} mapRow(ResultSet rs, int rowNum) throws SQLException {
			${name} vo = new ${name}();${vo}
			return vo;
		}
	};

}
